/*   Carina
 *   Copyright (C) 2009 2010 2011  Zdravko Velinov
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _PROPERTY_EDITOR_HH_
#define _PROPERTY_EDITOR_HH_

#include "carina/common/global.hh"
#include "carina/common/ces-file.hh"
#include "carina/common/containers.hh"
#include "carina/attribute.hh"
#include "carina/math.hh"

#include "ui_property-editor.h"

#include <QLineEdit>
#include <QDockWidget>
#include <QItemDelegate>

using namespace Carina;

struct Editable
{
    CESAttributeContainer&  m_CESAttributes;
    ConfigurablePtr         m_CarinaConfigurable;

    Editable(CESAttributeContainer& ces_attr, const ConfigurablePtr& carina_conf)
        :   m_CESAttributes(ces_attr),
            m_CarinaConfigurable(carina_conf) {}
};

typedef shared_ptr<Editable> EditablePtr;

class PropertyTreeModel;

class Property;
typedef shared_ptr<Property> PropertyPtr;

class PropertyTreeDelegate: public QItemDelegate
{
public:
    virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const;

    virtual void setEditorData(QWidget* editor, const QModelIndex& index) const;
    virtual void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index ) const;

    virtual void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const;
};

class PropertyTreeModel: public QAbstractItemModel
{
    DynamicArray<PropertyPtr> m_Properties;
public:
    virtual QModelIndex parent(const QModelIndex& index) const;
    virtual QModelIndex index(int row, int column, const QModelIndex& parent=QModelIndex()) const;
    virtual QVariant data(const QModelIndex& index, int role=Qt::DisplayRole) const;
    
    virtual bool setData(const QModelIndex& index, const QVariant& value, int role=Qt::EditRole);
    virtual Qt::ItemFlags flags(const QModelIndex& index) const;

    virtual QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const;

    virtual int rowCount(const QModelIndex & parent=QModelIndex()) const;
    virtual int columnCount(const QModelIndex & parent=QModelIndex()) const;

    virtual bool insertRows(int row, int count, const QModelIndex& parent=QModelIndex());
    virtual bool removeRows(int row, int count, const QModelIndex& parent=QModelIndex());

    bool insertProperty(const PropertyPtr& _property);
    void clear();
};

class Vector2Editor: public QWidget
{
    bool        m_IsNormalized;
    QLineEdit*  m_LineEdits[2];
public:
	Vector2Editor(VarRange range = CE_RANGE_NONE, QWidget* parent = nullptr);

    Vector2 getValue() const;
    void setValue(const Vector2& vec);
};

class Vector3Editor: public QWidget
{
    bool        m_IsNormalized;
    QLineEdit*  m_LineEdits[3];
public:
	Vector3Editor(VarRange range = CE_RANGE_NONE, QWidget* parent = nullptr);

    Vector3 getValue() const;
    void setValue(const Vector3& vec);
};

class Vector4Editor: public QWidget
{
    bool        m_IsNormalized;
    QLineEdit*  m_LineEdits[4];
public:
	Vector4Editor(VarRange range = CE_RANGE_NONE, QWidget* parent = nullptr);

    Vector4 getValue() const;
    void setValue(const Vector4& vec);
};

class PropertyEditor: public QDockWidget
{
    Q_OBJECT

    Ui::PropertyEditor      m_PropEdit;
    PropertyTreeModel       m_PropModel;
    PropertyTreeDelegate    m_PropDelegate;
public:
    PropertyEditor();

public slots:
    void setEditable(const EditablePtr& editable);
};

#endif /* _PROPERTY_EDITOR_HH_ */